#include "functions.h"

void population_merge(){
  int i, j ,k;

  // Layer 0
  for( j = 0; j < each_individuals; j++ ){
    for( k = 0; k < number_of_dimensions; k++ ){
      archive[ 0 ].individuals[ j ].design_variables[ k ] = layers[ 0 ].individuals[ j ].design_variables[ k ];
      archive[ 0 ].individuals[ j + each_individuals ].design_variables[ k ] = layers[ 1 ].individuals[ j ].design_variables[ k ];
    }
    archive[ 0 ].individuals[ j ].function_value = layers[ 0 ].individuals[ j ].function_value;
    archive[ 0 ].individuals[ j + each_individuals ].function_value = layers[ 1 ].individuals[ j ].function_value;
  }

  // Layer L - 1
  for( j = 0; j < each_individuals; j++ ){
    for( k = 0; k < number_of_dimensions; k++ ){
      archive[ number_of_layers - 1 ].individuals[ j ].design_variables[ k ] = 
	layers[ number_of_layers - 2 ].individuals[ j ].design_variables[ k ];

      archive[ number_of_layers - 1 ].individuals[ j + each_individuals ].design_variables[ k ] = 
	layers[ number_of_layers - 1 ].individuals[ j ].design_variables[ k ];
    }
    archive[ number_of_layers - 1 ].individuals[ j ].function_value = 
      layers[ number_of_layers - 2 ].individuals[ j ].function_value;

    archive[ number_of_layers - 1 ].individuals[ j + each_individuals ].function_value = 
      layers[ number_of_layers - 1 ].individuals[ j ].function_value;
  }

  // Layer from 2 to L - 2
  for( i = 1; i < number_of_layers - 1; i++ ){
    for( j = 0; j < each_individuals; j++ ){
      for( k = 0; k < number_of_dimensions; k++ ){

	archive[ i ].individuals[ j ].design_variables[ k ] = layers[ i - 1 ].individuals[ j ].design_variables[ k ];
	archive[ i ].individuals[ j + each_individuals ].design_variables[ k ] = layers[ i ].individuals[ j ].design_variables[ k ];
	archive[ i ].individuals[ j + each_individuals * 2 ].design_variables[ k ] = layers[ i + 1 ].individuals[ j ].design_variables[ k ];

      }
      archive[ i ].individuals[ j ].function_value = layers[ i - 1 ].individuals[ j ].function_value;
      archive[ i ].individuals[ j + each_individuals ].function_value = layers[ i ].individuals[ j ].function_value;
      archive[ i ].individuals[ j + each_individuals * 2 ].function_value = layers[ i + 1 ].individuals[ j ].function_value;
    }
  }

}

void initialize_individuals(){
  int i, j, k;

  for( i = 0; i < number_of_layers; i++ ){
    for( j = 0; j < each_individuals; j++ ){
      for( k = 0; k < number_of_dimensions; k++ ){

	layers[ i ].individuals[ j ].design_variables[ k ] = get_random_double_value( lower_limit, upper_limit );

      }

      layers[ i ].individuals[ j ].function_value = evaluate( layers[ i ].individuals[ j ].design_variables );

    }
  }

}

void population_sort( INDIVIDUAL *individuals, const int num ){
  qsort( individuals, num, sizeof( INDIVIDUAL ), ( int(*)( const void*, const void* ))individual_comp );
}

int individual_comp( const INDIVIDUAL *v0, const INDIVIDUAL *v1 ){

  if( ( strcmp( function_name, "f1" ) == 0 ) || ( strcmp( function_name, "f2" ) == 0 ) | ( strcmp( function_name, "f3" ) == 0 ) )
    {

      if( v0->function_value < v1->function_value )
	return 1;
      else
	return -1;

    } else{

    if( v0->function_value < v1->function_value )
      return -1;
    else
      return 1;
  }
}
